// 分组背包
int n, m;
vector<int> v[maxn], w[maxn];
int f[max_size]; // 考虑前 i 个物品，选择总体积为 j 的最大总价值
// f[j]=max(f[j_pre], f[j_pre−w[i][k]]+v[i][k])
int main() {
    for (int i = 1; i <= n; i++)              // 循环每一组
        for (int j = m; j >= 0; j--)          // 循环背包容量
            for (int k = 1; k <= cnt[i]; k++) // 最后循环该组的每一个物品，防止重复选择
                if (j >= w[i][k])
                    dp[j] = max(dp[j], dp[j - w[i][k]] + v[i][k]); // 像0-1背包一样状态转移
}